# -*- coding:utf-8 -*-


"""
# 递归
# 递归的性能
# 斐波那契数列的改进
# 生成器
# 无限循环
# yield from
"""

# 递归
"""
pre = 0
cur = 1
print(pre,cur,end='\t')

print("~~~~~~~~~~~~~~")
n = 4

for i in range(n-1):
    pre,cur = cur,pre + cur 
    print(cur,end='\t\n')


# F(0) = 0,F(1) = 1,F(n)=F(n-1)+F(n-2)

def fib(n):
    return 1 if n < 2 else fib(n-1) + fib(n-2)

for i in range(5):
    print(fib(i),end='')

print(fib(3)+fib(2))
print(fib(3))
print(fib(2))
print(fib(1))
"""


# 递归的性能
"""
# for循环
import datetime
start = datetime.datetime.now()
pre = 0
cur = 1
print(pre,cur,end='')
n = 35
for i in range(n-1):
    pre,cur = cur,pre + cur
    print(cur,end='')

delta = (datetime.datetime.now()- start).total_seconds()
print(delta)

print("~"*30)

# 递归的性能
import datetime
n = 35
start = datetime.datetime.now()
def fib(n):
    return 1 if n < 2 else fib(n-1) + fib(n-2)

for i in range(n):
    print(fib(i),end='')

delta = (datetime.datetime.now() - start).total_seconds()
print(delta)


# 斐波那契数列的改进
pre = 0
cur = 1
print(pre,cur,end='')
def fib(n,pre=0,cur=1):
    pre,cur = cur,pre + cur
    print(cur,end='')
    if n == 2:
        return
    fib(n-1,pre,cur)

'''
改进说明:
左边的fib函数和循环类似
参数n是边界条件,用n来计数.
上一次的计算结果直接作为函数的实参.
效率很高,
和循环比较,性能相近,递归有深度限制。
'''
"""

# 生成器
"""
def inc():
    for i in range(5):
        yield i 

print(type(inc))
print(type(inc()))
x = inc()
print(type(x))
print(next(x))

for m in x:
    print(m,'*')

for m in x:
    print(m,'**')

print("~"*30)
y = (i for i in range(5))
print(type(y))
print(next(y))
print(next(y))
'''
普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行.
生成器函数等价于生成器表达式,只不过生成器函数更复杂.
'''
"""


"""
def gen():
    print('line 1')
    yield 1
    print('line 2')
    yield 2
    print('line 3')
    return 3

print(next(gen()))
print(type(next(gen())))
g = gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g,'end'))
'''
在生成器函数中,使用多个yield语句,执行一次后会暂停执行,把yield表达式的值返回.
再次执行会执行到下一个yield语句.
return语句依然可以终止函数运行,但return语句的返回值不能被获取到.
return会导致无法继续获取下一个值,抛出StopIteration异常.
如果函数没有显示的return语句,如果生成器函数执行到结尾,一样会抛出StopIteration异常。
'''
"""


# 无限循环
'''
def counter():
    i = 0
    while True:
        i += 1
        yield i 

def inc(c):
    return next(c)

c = counter()
print(inc(c))
print(inc(c))
'''

'''
def counter():
    i = 0
    while True:
        i += 1
        yield i 

def inc():
    c = counter()
    return next(c)

print(inc())
print(type(inc()))
'''


# yield from
"""
def inc():
    for x in range(1000):
        yield x

foo = inc()
print(next(foo))
print(next(foo))
print(next(foo))

# 上面代码等价于
def inc():
    yield from range(1000)

foo = inc()
print(next(foo))
print(next(foo))
print(next(foo))


# 从可迭代对象中一个个拿元素
def counter(n): #生成器,迭代器
    for x in range(n):
        yield x 

def inc(n):
    yield from counter(n)

foo = inc(10)
print(next(foo))
print(next(foo))
"""
